package com.exam.base.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.nio.channels.FileChannel;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;

public class ControllerUtil {
	private ControllerUtil()
	{
	}

	/**
	 * 下载文件
	 */
	public static void downFile(HttpServletRequest request, HttpServletResponse response, String path, String fileName) throws Exception
	{
		downFile(request, response, path, fileName);
	}

	/**
	 * 下载文件
	 */
	public static void downFile(HttpServletRequest request, HttpServletResponse response, File file, String fileName) throws Exception
	{
		downFile(request, response, new FileInputStream(file), fileName);
	}

	/**
	 * 下载文件
	 */
	public static void downFile(HttpServletRequest request, HttpServletResponse response, InputStream fis, String fileName) throws Exception
	{
		OutputStream output = null;
		try
		{
			response.reset();
			response.addHeader("Content-Disposition", "attachment;filename=\"" + encodeDownloadFileName(fileName, request) + "\"");
			response.setContentType("applicatoin/octet-stream");
			// response.addHeader("Content-Length", "" + file.length());
			output = response.getOutputStream();
			byte[] buffer = new byte[1024 * 512];
			int length;
			while ((length = fis.read(buffer)) > 0)
			{
				output.write(buffer, 0, length);
			}
			output.flush();
		}
		finally
		{
			IOUtils.closeQuietly(fis);
			IOUtils.closeQuietly(output);
		}
	}

	/**
	 * 处理下载文件名称乱码问题
	 * @param fileName 文件名称
	 * @param request 请求对象
	 * @return 编码之后的文件名称
	 * @throws IOException 异常
	 */
	public static String encodeDownloadFileName(String fileName, HttpServletRequest request) throws IOException
	{
		String userAgent = request.getHeader("User-Agent");
		String newFilename = URLEncoder.encode(fileName, "UTF-8").replace("+", " ");
		if (null == userAgent)
		{
			return newFilename;
		}

		userAgent = userAgent.toLowerCase();
		if (userAgent.indexOf("edge") != -1 || userAgent.indexOf("trident") != -1)
		{
			return newFilename;
		}
		else
		{
			return new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
		}
	}

	public static void printJson(HttpServletResponse response, Object data)
	{
		PrintWriter out = null;
		try
		{
			response.setContentType("application/json");
			response.setHeader("Pragma", "No-cache");
			response.setHeader("Cache-Control", "no-cache");
			response.setCharacterEncoding("UTF-8");
			out = response.getWriter();
			out.print(data);
			out.flush();
			out.close();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			IOUtils.closeQuietly(out);
		}
	}

	/**
	 * 下载文件
	 */
	public static void downFileEsb(HttpServletRequest request, HttpServletResponse response, File file, String fileName) throws Exception
	{
		OutputStream toClient = null;
		InputStream fis = null;
		try
		{
			// 以流的形式下载文件。
			fis = new BufferedInputStream(new FileInputStream(file));
			byte[] buffer = new byte[fis.available()];
			fis.read(buffer);
			fis.close();
			// 清空response
			response.reset();
			// 设置response的Header
			response.addHeader("Content-Disposition", "attachment;filename=" + encodeDownloadFileName(fileName, request));
			response.addHeader("Content-Length", "" + getFileSize(file));
			toClient = new BufferedOutputStream(response.getOutputStream());
			response.setContentType("application/x-msdownload");
			// 解密
			toClient.write(buffer);
			toClient.flush();
			toClient.close();
		}
		finally
		{
			IOUtils.closeQuietly(fis);
			IOUtils.closeQuietly(toClient);
		}
	}

	/**
	 * 计算文件大小文件大小
	 * @param filePath 文件路径例如：E:\\imgData\\afr\\9211496189393485.jpg
	 * @return 文件大小 Kb
	 */
	public static long getFileSize(File file) throws Exception
	{
		FileInputStream fis = null;
		FileChannel fc = null;
		try
		{
			long fileSize = 0l;
			fis = new FileInputStream(file);
			fc = fis.getChannel();
			fileSize = fc.size() / 1024;
			return fileSize;
		}
		finally
		{
			if (fc != null)
			{
				fc.close();
			}
			IOUtils.closeQuietly(fis);
		}
	}
}
